﻿using System;
using System.Collections.Generic;
using GSPMigratorCore.Misc;
using GSPMigratorCore.NamingConventions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace GSPMigratorCore.Helper
{
    public class FolderCreationHelper
    {
        public static SPFolder Create(string SPDocLibFullPath, string SPURL, string taxonomy, string replaceWith)
        {
            SPFolder oFolder = null;
            try
            {
                //TODO: Info logging
                List<string> temp = SplitFolderNameByPath(RemoveRootFolderName(taxonomy), replaceWith);
                oFolder = CreateSPFolder(SPDocLibFullPath, SPURL, temp);
            }
            catch (GSPException GSPex)
            { 
                //TODO: Handled error logging
            }
            catch (Exception ex)
            { 
                //TODO: Unhandled error logging
            }
            return oFolder;
        }

        #region private methods

        private static List<string> PrepareFullURL(string SPURL, string SPDocLibFullPath, List<string> folderNameByPath)
        {
            try
            {
                //TODO: Info logging
                string temp = SPURL + SPDocLibFullPath + GSPConstants.URLDelimiter + folderNameByPath[0] + GSPConstants.URLDelimiter;
                folderNameByPath[0] = temp;

                for (int i = 1; i < folderNameByPath.Count; i++)
                {
                    temp += folderNameByPath[i] + GSPConstants.URLDelimiter;
                    folderNameByPath[i] = temp;
                }
            }
            catch (GSPException GSPEx)
            { 
                //TODO: Handled error logging
            }
            catch (Exception ex)
            {
                //TODO: Unhandled error logging
            }
            return folderNameByPath;
        }

        private static List<string> SplitFolderNameByPath(string folderPath, string replaceWith)
        {
            //TODO: info logging   
            string[] delimiter = { GSPConstants.DATDelimiter };
            string[] decodedFolders = folderPath.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
            List<string> encodedFolders = new List<string>();

            try
            {             
                foreach (string folder in decodedFolders)
                {
                    //TODO: debug logging
                    string temp = folder;
                    temp = GSPReplacer.GetSharePointFriendlyName(folder, 0, GSPReplacer.MAXFOLDERLENGTH, replaceWith);
                    encodedFolders.Add(temp);
                }
            }
            catch (GSPException GSPex)
            {
                //TODO: Handled error logging
            }
            catch (Exception ex)
            {
                //TODO: Unhandled error logging
            }
            return encodedFolders;
        }

        private static SPFolder CreateSPFolder(string SPDocLibFullPath, string SPURL, List<string> folderNameByPath)
        {
            //TODO: debug info logging
            SPFolder oFolder = null;
            try
            {
                //TODO: debug info logging
                using (SPSite oSite = new SPSite(SPURL))
                {
                    //TODO: debug info logging
                    using (SPWeb oWeb = oSite.OpenWeb())
                    {
                        string temp = SPURL + "/" + SPHttpUtility.UrlPathEncode(SPDocLibFullPath, false) + "/";
                        SPList oList = oWeb.GetList(temp);
                        string nestedFolder = string.Empty;

                        foreach (string folderName in folderNameByPath)
                        {
                            nestedFolder += "/" + folderName;

                            if (nestedFolder.StartsWith("/"))
                                nestedFolder = nestedFolder.Substring(1);

                            oFolder = oWeb.GetFolder(SPDocLibFullPath + GSPConstants.URLDelimiter + nestedFolder);

                            #region check folder existence then create if don't exists
                            if (!oFolder.Exists)
                            {
                                //TODO: debug info logging
                                if (!oList.EnableFolderCreation)
                                {
                                    oList.EnableFolderCreation = true;
                                    oList.Update();
                                }
                                oFolder = oWeb.GetFolder(folderName);
                                if (!oFolder.Exists)
                                {
                                    //TODO: optimized add
                                    //TODO: debug info logging
                                    SPListItem newFolder = oList.Items.Add("", SPFileSystemObjectType.Folder, SPHttpUtility.UrlPathDecode(nestedFolder, false).Trim('/'));
                                    newFolder.Update();
                                    oFolder = newFolder.Folder;
                                    //TODO: debug info logging
                                }
                            }
                            #endregion

                            // Still no folder, throw error
                            if (oFolder == null)
                                throw new SPException(string.Format("The folder '{0}' could not be found.", folderNameByPath[0]));
                        }
                        //set folder to deepest folder
                        oFolder = oWeb.GetFolder(SPDocLibFullPath + GSPConstants.URLDelimiter + nestedFolder);
                    }
                }
            }
            catch (GSPException GSPex)
            {
                //TODO: Handled error logging
            }
            catch (Exception ex)
            {
                //TODO: Unhandled error logging
                throw ex;
            }
            return oFolder;
        }

        #endregion

        #region internal utilities

        internal static string GetEncodedFolderName(string folderName)
        {
            //TODO: Info logging
            string url = string.Empty;
            try
            {
                //TODO: Debug info logging
                url = SPHttpUtility.UrlPathEncode(folderName, false);
            }
            catch (GSPException GSPex)
            {
                //TODO: Handled error logging
            }
            catch (Exception ex)
            { 
                //TODO: Unhandled error logging
            }
            return url;
        }

        internal static string RemoveRootFolderName(string fullPath)
        {
            //TODO: Info logging
            try
            {
                //TODO: Debug info logging
                fullPath = fullPath.Replace(@"DIR: ", string.Empty);
            }
            catch (GSPException GSPex)
            {
                //TODO: Handled error logging
            }
            catch (Exception ex)
            { 
                //TODO: Unhandled error logging
            }
            return fullPath;
        }

        #endregion
    }
}
